import numpy as np

buffer = np.array([0, 0])
mode_mtx = np.full([4, 6], 99)


# 参考的是 https://blog.csdn.net/zhouxuanyuye/article/details/73729754 的卷积码模型
def generation(input_code):
    global buffer
    code_length = len(input_code)
    output = np.arange(2 * code_length)
    for i in range(0, code_length):
        j = 2 * i
        input_now = input_code[i]
        output[j] = (buffer[0] + buffer[1] + input_now) % 2
        output[j + 1] = (input_now + buffer[1]) % 2
        buffer = np.roll(buffer, 1)
        buffer[0] = input_now
    return output


def mode2fun(rx_code, index, a):
    a2array = np.array([0, 0])
    a2array[1] = a % 2
    a2array[0] = a / 2
    return (rx_code[index] + a2array[0]) % 2 + (rx_code[index + 1] + a2array[1]) % 2


def decode_mtx_gen(rx_code):
    # 第二层
    mode_mtx[0][1] = mode2fun(rx_code, 0, 0)
    mode_mtx[2][1] = mode2fun(rx_code, 0, 3)
    # 第三层
    mode_mtx[0][2] = mode2fun(rx_code, 2, 0) + mode_mtx[0][1]
    mode_mtx[1][2] = mode2fun(rx_code, 2, 2) + mode_mtx[2][1]
    mode_mtx[2][2] = mode2fun(rx_code, 2, 3) + mode_mtx[0][1]
    mode_mtx[3][2] = mode2fun(rx_code, 2, 1) + mode_mtx[2][1]
    # 第四层
    for i in range(2, 5):  # range 是前闭后开区间，包含第一个但是不包含最后一个
        mode_mtx[0][i + 1] = min((mode2fun(rx_code, 2 * i, 0) + mode_mtx[0][i]),
                                 (mode2fun(rx_code, 2 * i, 3) + mode_mtx[1][i]))
        mode_mtx[1][i + 1] = min((mode2fun(rx_code, 2 * i, 2) + mode_mtx[2][i]),
                                 (mode2fun(rx_code, 2 * i, 1) + mode_mtx[3][i]))
        mode_mtx[2][i + 1] = min((mode2fun(rx_code, 2 * i, 3) + mode_mtx[0][i]),
                                 (mode2fun(rx_code, 2 * i, 0) + mode_mtx[1][i]))
        mode_mtx[3][i + 1] = min((mode2fun(rx_code, 2 * i, 1) + mode_mtx[2][i]),
                                 (mode2fun(rx_code, 2 * i, 2) + mode_mtx[3][i]))

    return mode_mtx


def get_reflect_route(index, layer):
    if layer >= 1:
        if index == 3:
            return [1, [2, 3]]
        if index == 2:
            return [1, [0, 1]]
        if index == 1:
            return [0, [2, 3]]
        if index == 0:
            return [0, [0, 1]]


def decode_conv(mtx):
    decode = [0, 0, 0, 0, 0]
    length = len(mtx[0])
    list = mode_mtx[:, 5].tolist()
    index = list.index(min(list))
    for layer in range(0, length):
        temp = get_reflect_route(index, length - layer - 1)
        if (length-layer-2<0):
            break
        decode[length - layer - 2] = temp[0]  # 注意index！！！！
        m1 = mode_mtx[temp[1][0], length - layer - 2]
        m2 = mode_mtx[temp[1][1], length - layer - 2]
        if m1 < m2:
            index = temp[1][0]
        else:
            index = temp[1][1]
    return decode


code = np.array([1, 1, 0, 1, 1])
tx_code = generation(code)
print(tx_code)
'''
经过调制射频等等乱七八糟的方式，然后加信道
然后经过信道后解射频解调制均衡然后得到rx_code
'''
rx_code = np.array([1, 1, 0, 1, 0, 1, 1, 0, 0, 1])
# 维特比译码错误度量思路，就是状态转移累计错误长度。
decode_mtx_gen(rx_code)

print(decode_conv(mode_mtx))
